﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GcmpRenderingInterface.h"

namespace gcmp
{
    /// \brief 底层渲染设备
    enum class RenderSystem : int32_t
    {
        Unknown = 0,         ///< 未知设备
        OpenGL = 1,          ///< OpenGL设备
        DirectX9 = 2,        ///< DirectX 9设备(暂不支持)
        DirectX11 = 3,       ///< DirectX 11设备(暂不支持)
        Angle = 4,           ///<  Angle 设备
        DirectX12 = 5        ///< DirectX 12设备
    };

    /// \brief 显卡厂商
    enum class GraphicsCardVendor : int32_t
    {
        Unknown = -1,   ///< 未知厂商
        NVIDIA = 0,     ///< NVIDIA
        AMD = 1,        ///< AMD
        Intel = 2       ///< Intel
    };

    /// \brief 问题建议
    enum class DiagnoseSolution : int32_t
    {
        NotInitialized = -1000,            ///< 其它错误
        SystemNotSupported = -4,           ///< 系统版本过低，需要XP及以上
        DBEmpty = -3,                      ///< 数据库空，采用常规模式启动，有问题走报告流程
        NoSuchRecord = -2,                 ///< 数据库无对应记录，采用常规模式启动，有问题走报告流程
        TrySoftWareMode = -1,              ///< 尝试切换到软件模拟模式。显卡不兼容，CPU无记录，可尝试切换软件模拟，有问题走报告流程
        OK = 0,                            ///< 无兼容性问题
        UpdateDisplayCard = 1,             ///< 需要升级显卡硬件。显卡不兼容，CPU不支持软件模拟
        UpdateDriver = 2,                  ///< 如果有显示问题，需要升级驱动，驱动未经过WHQL认证
        AddMemory = 3,                     ///< 内存不足
        SwitchDisplayCard = 4,             ///< 切换显卡，多显卡
        SwitchSoftWareMode = 5,            ///< 切换到软件模拟模式
        SwitchSimpleRender = 6,            ///< 切换简化流程
        SwitchNoFBORender = 7,             ///< 禁用FBO
        SwitchDriverThreadOptmize = 8,     ///< 关闭驱动控制面板中的多线程加速
        SwitchAngleMode = 9,               ///< Angle模式，底层用D3D渲染
        SwitchDX12Mode = 10,               ///< DX12
    };


    /*
    ** @brief 主显示器与显卡接线情况
    */
    enum class MonitorsPrimaryAdapterProblem : int32_t
    {
        Error_DisplayCardError,// "主显示器所处显卡运行在Microsoft基本显示驱动程序上，该显卡可能被禁用，或者未安装驱动程序"
        Switch_DisplayAdapter, //存在独立显卡，主显示器当前连接的显卡是集成显卡，而不是可用的独立显卡		
        Error_MonitorMissing,//"无法识别主显示器，存在未知问题"（也可能是远程桌面连接）
        MonitorAdaptorOK,    //主显示器接线正常
        Unknown,    //未知
    };

    /// \brief 本机硬件信息   
    struct HardWareInfo
    {
        HardWareInfo()
            : ProcessorName(L"")
            , DefDispalyCardName(L"")
            , OSName(L"")
            , OSArchitecture(L"") 
        {
        }

        std::wstring ProcessorName;       ///< 处理器
        std::wstring DefDispalyCardName;  ///< 默认显卡
        std::wstring OSName;              ///< 操作系统名称
        std::wstring OSArchitecture;      ///< 操作系统类型
    };

    /// \brief 渲染引擎上下文
    class GCMP_RENDERING_INTERFACE_EXPORT IRenderEngineContext
    {
    public:
        /// \brief 析构函数
        virtual ~IRenderEngineContext();

        /// \brief 获取渲染引擎上下文
        /// \return 渲染引擎上下文指针
        static IRenderEngineContext* GetInstance();

        /// \brief 获取本机绘制模式：软件模拟或硬件加速
        /// \return true,软件模拟；false，硬件加速
        virtual bool IsOnSoftwareMode() const = 0;

        /// \brief 初始化显示引擎，程序启动后，使用显示引擎前必须调用
        /// \return 是否初始化成功，如果发现OpenGL版本过低(<2.0)，显示引擎会工作异常甚至崩溃，该函数会返回false，应用层酌情给予用户提示，并终止后续操作
        virtual bool InitializeRenderEngine() = 0;

        /// \brief 初始化显示引擎失败错误码获取
        /// \return 返回失败错误码
        virtual int GetRenderEngineErrorCode() const = 0;

        /// \brief 初始化材质
        /// \return void
        virtual void InitializeMaterialManager() = 0;

        /// \brief 反初始化显示引擎，程序结束前，使用完显示引擎后（包括析构CViewer）必须调用
        /// \return void
        virtual void UninitializeRenderEngine() = 0;

        /// \brief 加载视频插件，在使用视频功能（如动画）之前需要加载
        /// \return 是否加载成功
        virtual bool LoadVideoFFmpegPlugin() = 0;

        /// \brief 卸载视频插件
        /// \return 是否卸载成功
        virtual bool UnLoadVideoFFmpegPlugin() = 0;

        /// \brief 获取当前的渲染引擎，默认为OpenGL
        /// \return 底层渲染设备
        virtual RenderSystem GetRenderSystem() const = 0;

        /// \brief 查询Windows操作系统版本
        /// \return const std::wstring Windows操作系统版本
        virtual std::wstring WindowsOSVersion() const = 0;

        /// \brief 查询显卡支持的最高级别D3D_FEATURE_LEVEL
        /// \param[in] i 显卡索引
        /// \return const std::wstring D3D_FEATURE_LEVEL对应的字串
        virtual std::wstring GPUD3DFeatureLevel(int i) const= 0;

        /// \brief 查询显卡信息
        /// \return int 显卡数量
        virtual int GPUCount() const = 0;

        /// \brief 查询当前使用显卡的索引
        /// \return int 显卡索引
        virtual int GPUUsed()const = 0;

        /// \brief 查询显卡厂商
        /// \param[in] i 显卡索引
        /// \EnumVendor 厂商
        virtual GraphicsCardVendor GPUVendor(int i) const = 0;

        /// \brief 查询显卡驱动日期
        /// \param[in] i 显卡索引
        /// \return std::wstring 显卡驱动日期，格式“YYYYMMDD”
        virtual std::wstring GPUDriverDate(int i) const = 0;

        /// \brief 获取本机硬件信息
        /// \param[out] HardWareInfo 硬件信息
        /// \return true，获取成功；false，获取失败
        virtual bool GetHardWareInfo(HardWareInfo& info) const = 0;

        /// \brief 查询显卡名
        /// \param[in] i 显卡索引
        /// \return std::wstring 显卡型号名
        virtual std::wstring GPUCaption(int i) const = 0;

        /// \brief 查询显卡即插即用设备ID
        /// \param[in] i 显卡索引
        /// \return std::wstring ID字串
        virtual std::wstring GPUID(int i) const = 0;

        /// \brief 诊断系统，返回处理建议
        /// \param[in] dbPathName 数据库文件db.json路径名
        /// \param[out] dbSolution 数据库文件db.json中保存的配置
        /// \return EnumSolution 返回配置建议
        virtual DiagnoseSolution Diagnose(const std::wstring& dbPathName, DiagnoseSolution& dbSolution) const = 0;

        /// \brief 获取显卡是否支持实例渲染
        /// \return true,支持；false，不支持
        virtual bool IsSupportDrawInstanceData() const = 0;

        /// \brief 获取硬件是否支持FBO
        /// \return true,支持；false，不支持
        virtual bool IsSupportRSCFBO() const = 0;

        /// \brief 获取OpenGL版本号3.2f, 3是Major, 2是Minor
        /// \param[out] nMajor OpenGL大版本号
        /// \param[out] nMinor OpenGL小版本号
        /// \param[out] fVer 大版本号.小版本号
        /// \return true,获取成功；false，获取失败(opengl低于2.0，返回失败)
        virtual bool GetOpenGLVersion(int& nMajor, int& nMinor, float& fVer) const = 0;


        /// \brief checkMonitors 诊断主显示器与显卡接线情况
        /// \return int 返回主显示器接线情况建议，具体值参考EnumPrimaryAdapterProblem枚举类型说明
        virtual MonitorsPrimaryAdapterProblem CheckMonitors() const = 0;


        /// \brief获取驱动版本
        virtual std::wstring GetDriverVersion() const = 0;

        /// \brief 获取硬件是否支持VBO
        /// \return true,支持；false，不支持
        virtual bool IsSupportRSCVBO() const = 0;

        /**
        * IsLaptop
        * @brief 诊断机器是否是笔记本
        * @return bool 返回true，代表是笔记本
        * 由于笔记本硬件较复杂，本接口不能保证100%检测正确，需保守使用，建议做为出错时的辅助检测手段
        */
        virtual bool IsLaptop() const = 0;
    };
}
